#include "outilParsage.h"

string IToSTroisChiffres(int n){
    string s;
    if(n<100){
        s+='0';
    }
    if(n<10){
        s+='0';
    }
    std::ostringstream oss;
    oss<<n;
    s+=oss.str();
    return s;
}

string IToS(int i){
    std::ostringstream oss;
    oss << i;
    return oss.str();
}

void transformer (string * s, char x, char v){ //remplace tout les x par des v dans s.
    for(int i =0; i<s->size(); i++){
        if((*s)[i]==x){
            (*s)[i]=v;
        }
    }



}

bool estUnChiffre(char i){
    return (i>47 && i<58);
}

bool estUneLettre(char i){
    if((i>64 && i<91) || (i>96 && i<122)){
        //cout<<"est une lettre : "<<i<<endl;
        return true;
    } else {
    /*return ((i>64 && i<91) || (i>96 && i<122));
    */
        return false;
    }
}

char autre(char couleur){
    if(couleur=='B')
        return 'W';
    else
        return 'B';
}

//avance i un caractere apres le symbole recherché.
bool lireChar(int * i, string * ligne, char caractere){
    while((*ligne)[*i]!=caractere &&  *i< ligne->size()){
        (*i)++;
    }
    //(*i)++;
    return (*i<= ligne->size());

}

//re'copie ligne dans f de i jusqu'au caractère c, avance i.
void lireChar(int * i, string * ligne, char c, ofstream * f){
    //(*i)--;
    //(*f)<<" lire char : "<<endl;
    while((*ligne)[*i]!=c){
        (*f)<<(*ligne)[*i];
        (*i)++;
    }
    //(*i)++;
}

//recopie ligne dans s de i jusqu'au caractère c, avance i.
void lireChar(int * i, string * ligne, char c, string * s){
    //(*i)--;
    cerr<<"trace : lireChar : "<<*i<<" ( "<<(*ligne)[*i]<<" ) : "<<*ligne<<" : "<<c<<endl;
    //*s+=(*ligne)[*i];
    //(*i)++;
    //*s+=(*ligne)[*i];
    //(*i)++;
    while((*ligne)[*i]!=c){
        *s+=(*ligne)[*i];
        (*i)++;
    }
    //(*i)++;
    cerr<<"recopié : "<<*s<<endl;
    cerr<<" i : "<<*i<<endl;
}

//recopie ligne dans s de i jusqu'à la fin, avance i.
void recopieFin(int * i, string * ligne, string * s){
    cerr<<"recopieFin : ("<<*i<<" - "<<*ligne  <<endl;
    while(*i<ligne->size()){
        cerr<<(*ligne)[*i];
        *s+=(*ligne)[*i];
        (*i)++;
    }
    //(*i)++;
    cerr<<endl;
}

bool lireMot(int * i, string * ligne, string motRecherche){
    //cout<<"lire mot : "<<motRecherche<<endl;
    //cout<<" ligne : "<<*ligne<<endl;
    bool trouve = false;
    int it;
    while(!trouve && *i<ligne->size()){
        while((*ligne)[*i]!=motRecherche[0] && *i<ligne->size()){
            (*i)++;
        }
        for(it =0; it<motRecherche.size() && motRecherche[it]==(*ligne)[*i] && *i<ligne->size(); it++){
            cout<<(*ligne)[*i];
            (*i)++;
        }
        cout<<endl;
        if(it==motRecherche.size()){
            trouve= true;
        }
    }
    cout<<endl<<"trouve : "<<trouve<<endl;
    //(*i)++;
    return trouve;
}


string lireMot(int * i, string * ligne, vector <string> motRecherche){ //retourne le mot trouvé.
    for(int j=0; j<motRecherche.size(); j++){
        //cout<<"lire mot : "<<motRecherche[j]<<endl;
    }
    //cout<<" ligne : "<<*ligne<<endl;
    bool trouve = false;
    vector <string> motTemp; //les mots eligibles.
    motTemp.resize(motRecherche.size());
    for(int j =0; j<motRecherche.size(); j++){
        motTemp[j]=motRecherche[j];
    }
    vector <int> place;
    place.resize(motTemp.size(),0);
    int it;
    int tailleMT;
    while(!trouve && *i<ligne->size()){
        tailleMT = motTemp.size();
        //cout<<*i<<" - " <<(*ligne)[*i]<<" : "<<tailleMT<<endl;
        for(int j=0; j<tailleMT; j++){
            //cout<<j<<"ieme mot scanné : "<<motTemp[j]<<"(lettre "<<place[j]<<")"<<endl;
            if(egal((*ligne)[*i],motTemp[j][place[j]]) && *i<ligne->size()){
                place[j]++;
                //cout<<"j'ai "<<place[j]<<" lettres du mot "<<motTemp[j]<<endl;
                if(place[j]==motTemp[j].size()){
                    cout<<"mot trouvé!"<<motTemp[j][place[j]]<<endl;
                    return (motTemp[j]);
                }
                motTemp.push_back(motTemp[j]);
                place.push_back(0);
            } else if(j<motRecherche.size()){
                place[j]=0;
            } else {
                //cout<<"on ecrase : "<<motTemp[j]<<" : "<<j<<"ieme mot."<<endl;
                place.erase(place.begin()+j);
                motTemp.erase(motTemp.begin()+j);
                tailleMT--;
            }
        }
        (*i)++;
    }
    cout<<endl<<"trouve : "<<trouve<<endl;
    return "";
}

bool egal(char a, char b){//gestion des majuscules...
    if (a==b){
        return true;
    } else if(64<a<91 && 97<b<123 && a+32==b){
        return true;
    } else if(64<b<91 && 97<a<123 && b+32==a){
        return true;
    } else {
        return false;
    }
}


string lireMot(int * i, string * ligne, string * retour, vector <string> motRecherche){ //retourne le mot trouvé. Recopie dans retour la chaine de i au mot trouvé.
/*
    for(int j=0; j<motRecherche.size(); j++){
        cout<<"lire mot : "<<motRecherche[j]<<endl;
    }
    cout<<" ligne : "<<*ligne<<endl;
    cout<<" emplacement : "<<*i<<endl;
*/
    bool trouve = false;
    vector <string> motTemp; //les mots eligibles.
    motTemp.resize(motRecherche.size());
    for(int j =0; j<motRecherche.size(); j++){
        motTemp[j]=motRecherche[j];
    }
    vector <int> place;
    place.resize(motTemp.size(),0);
    int it;
    int tailleMT;
    while(!trouve && *i<ligne->size()){
        tailleMT = motTemp.size();
        //cout<<*i<<" - " <<(*ligne)[*i]<<" : "<<tailleMT<<endl;
        *retour+=(*ligne)[*i];
        for(int j=0; j<tailleMT; j++){
            //cout<<j<<"ieme mot scanné : "<<motTemp[j]<<"(lettre "<<place[j]<<")"<<endl;
            if(egal((*ligne)[*i],motTemp[j][place[j]]) && *i<ligne->size()){
                place[j]++;
                //cout<<"j'ai "<<place[j]<<" lettres du mot "<<motTemp[j]<<endl;
                if(place[j]==motTemp[j].size()){
                    cout<<"mot trouvé!"<<motTemp[j][place[j]]<<endl;
                    return (motTemp[j]);
                }
                motTemp.push_back(motTemp[j]);
                place.push_back(0);
            } else if(j<motRecherche.size()){
                place[j]=0;
            } else {
                //cout<<"on ecrase : "<<motTemp[j]<<" : "<<j<<"ieme mot."<<endl;
                place.erase(place.begin()+j);
                motTemp.erase(motTemp.begin()+j);
                tailleMT--;
            }
        }
        (*i)++;
    }
    cout<<endl<<"trouve : "<<trouve<<endl;
    return "";
}

bool lireMot(int * i, string * ligne, string motRecherche, int depacementMax){
    int maxValI = *i + deplacementMax;
    bool trouve = false;
    vector <string> motTemp; //les mots eligibles.
    motTemp.resize(motRecherche.size());
    for(int j =0; j<motRecherche.size(); j++){
        motTemp[j]=motRecherche[j];
    }
    vector <int> place;
    place.resize(motTemp.size(),0);
    int it;
    int tailleMT;
    while(!trouve && *i<ligne->size() && *i<maxValI){
        tailleMT = motTemp.size();
        //cout<<*i<<" - " <<(*ligne)[*i]<<" : "<<tailleMT<<endl;
        *retour+=(*ligne)[*i];
        for(int j=0; j<tailleMT; j++){
            //cout<<j<<"ieme mot scanné : "<<motTemp[j]<<"(lettre "<<place[j]<<")"<<endl;
            if(egal((*ligne)[*i],motTemp[j][place[j]]) && *i<ligne->size()){
                place[j]++;
                //cout<<"j'ai "<<place[j]<<" lettres du mot "<<motTemp[j]<<endl;
                if(place[j]==motTemp[j].size()){
                    cout<<"mot trouvé!"<<motTemp[j][place[j]]<<endl;
                    return (motTemp[j]);
                }
                motTemp.push_back(motTemp[j]);
                place.push_back(0);
            } else if(j<motRecherche.size()){
                place[j]=0;
            } else {
                //cout<<"on ecrase : "<<motTemp[j]<<" : "<<j<<"ieme mot."<<endl;
                place.erase(place.begin()+j);
                motTemp.erase(motTemp.begin()+j);
                tailleMT--;
            }
        }
        (*i)++;
    }
    cout<<endl<<"trouve : "<<trouve<<endl;
    return "";
}


string lireDeuxMots(int * i, string * ligne, vector <string> motRecherche, int tailleMax){ //renvoi la ligne entre les deux mots crées.
    string retour;
    retour = lireMot(i,ligne, motRecherche);
    if(retour == ""){
        return "";
    } else {
        cout<<"premier mot trouvé, " <<retour <<", on passe à la suite!"<<endl;
        int depart = (*i);
        (*i)++;
        string temp;
        temp = lireMot(i,ligne, &retour, motRecherche);
        if((*i)-depart+ temp.size()<tailleMax){
        //retour+=temp;
            if(temp== ""){
                cout<<"pas de deuxieme mot trouvé :s"<<endl;
                return "";
            } else {
                cout<<" deuxieme mot trouvé : "<<temp<<endl;
                (*i) -=(temp.size()+1);
                //(*i)--;

                return retour;
            }
        } else {
            cout<<"taille depassé ( "<<(*i)-depart+ temp.size() <<" )"<<endl;
            return lireDeuxMots(i, ligne, motRecherche, tailleMax);
        }
    }
}

bool lireDeuxMots(int * i, string * ligne, vector <string> motRecherche, int tailleMax, vector<string> retour){
    //renvoie vrai si deux mots trouvés proposés dans motRecherche sont trouvés dans ligne à une distance l'un de 'lautre inferieur à tailleMax.
    //retour récupère un tableau de 4 strings : 1 : mot 1. 2 : Mot 2. 3 : mocreau de phrase entre les mots.  4 : phrases competes contenant les mots.
    //vector<string> retour(4,"");
    motRecherche.push_back(".");
    string phrase;
    string demiPhrase;
    string mot;

    do{
        phrase="";
        mot = lireMot(i,ligne, &phrase ,motRecherche);
    } while(mot==".");
    if(mot == ""){
        return 0;
    } else {
        cout<<"premier mot trouvé, " <<mot <<", on passe à la suite!"<<endl;
        int depart = (*i);
        (*i)++;
        string temp;
        motRecherche.pop_back();
        temp = lireMot(i,ligne, &demiPhrase, motRecherche);
        if((*i)-depart+ temp.size()<tailleMax){ //Si le deuxieme mot ets pas trop loin du premier.
            if(temp== ""){
                cout<<"pas de deuxieme mot trouvé :s"<<endl;
                return 0;
            } else {
                cout<<" deuxieme mot trouvé : "<<temp<<endl;
                retour[0]=mot;
                retour[2]=mot;
                retour[1]=temp;
                retour[2]+=demiPhrase;
                phrase+=demiPhrase;
                lireChar(i, ligne, '.', &phrase);
                retour[3]=phrase;
                (*i) -=(temp.size()+1);
                return 1;
            }
        } else {
            cout<<"taille depassé ( "<<(*i)-depart+ temp.size() <<" )"<<endl;
            return 0;
        }
    }
}



//cherche un charactere parmi une liste dans la ligne, avance i au caractere suivant, et renvoi le caractere trouvé.
char lireChar(int * i, string * ligne, char * caractere, int taille){
    bool test = 1;
    while(test){
        for(int j=0; j<taille && test; j++){
            if((*ligne)[*i]==caractere[j])
                test = 0;
        }
        (*i)++;
    }
    char retour;
    (*i)--;
    if(test)
        retour = NULL;
    else
        retour = (*ligne)[(*i)];
    //(*i)++;
    return retour;
}

int lireNombre(int * i, string * ligne){
    bool neg = false;
    while(!estUnChiffre((*ligne)[*i]) /* && !estUneLettre((*ligne)[*i]) */){
        if(!neg && (*ligne)[*i]=='-'){
            neg=true;
        } else {
            neg=false;
        }
        (*i)++;
    }
    string temp;
    if(estUnChiffre((*ligne)[*i])){
        while(estUnChiffre((*ligne)[*i])){
            temp+=(*ligne)[*i];
            (*i)++;
        }
    } else {
        temp='0';
    }
    std::istringstream iss(temp);

    int nombre;
    iss >> nombre;
    if(neg){
        nombre = 0 - nombre;
    }
    //cout<<"nombre : "<<nombre<<endl;
    return nombre;
}

char nombreToLettre(int i){
    if(i>=0 && i<=26){
        return (char)(i+97);
    } else {
        return ' ';
    }
}

void supprimeCaractere(string * s, char c){ //supprime le caractère c dans s.
    for(int i=0; i<s->size(); i++){
        if((*s)[i]==c){
            s->erase(s->begin()+ i);
        }
    }
}


/*
Coup nombreToCoup(int n){
    Coup c;
    c.x=n/TAILLE;
    c.y=n%TAILLE;
    c.c='N';
    return c;
}
*/
